{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "移动到 PPDiffusersWebUI 同级目录才有效"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1><span style=\"background: linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet);  -webkit-background-clip: text;  -webkit-text-fill-color: transparent;\">二次元模型</span></h1>\n",
    "\n",
    "\n",
    "**单模型safetensors权重转换pd权重**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备工作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 解压转换工具\n",
    "!unzip data/data268105/convertkeys.zip"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 环境准备\n",
    "evn='''\n",
    "ppdiffusers==0.24.0 \n",
    "paddlenlp==2.7.2 \n",
    "'''\n",
    "with open(\"requirements.txt\", \"w\", encoding=\"utf-8\") as fp:\n",
    "    fp.writelines(evn)\n",
    "\n",
    "import os\n",
    "os.makedirs(\"~/external-libraries\", exist_ok=True)\n",
    "os.system(\"pip install -r requirements.txt -t ~/external-libraries\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型转换"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Animagine-xl-3.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 单文件权重转换safetensor，--model_name [待转换模型路径]\n",
    "!python convertkeys/convert_key.py \\\n",
    "    --model_name data/data268105/animagine-xl-3.1.safetensors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Pony-v6-XL"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 单文件权重转换safetensor，--model_name [待转换模型路径]\n",
    "!python convertkeys/convert_key.py \\\n",
    "    --model_name data/data270713/ponyDiffusionV6XL_v6TurboDPOMerge.safetensors\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 单文件权重转换safetensor，--model_name [待转换模型路径]\n",
    "!python convertkeys/convert_key.py \\\n",
    "    --model_name data/data270713/pony_pencil-XL-v1.0.2.safetensors\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 单文件权重转换safetensor，--model_name [待转换模型路径]\n",
    "!python convertkeys/convert_key.py \\\n",
    "    --model_name data/data270713/RealVisXL_V4.0.safetensors\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 单文件权重转换safetensor，--model_name [待转换模型路径]\n",
    "!python convertkeys/convert_key.py \\\n",
    "    --model_name data/data270713/RealVisXL_V4.0_Lightning.safetensors\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型测试\n",
    "\n",
    "重启内核"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "import warnings  \n",
    "warnings.filterwarnings(\"ignore\")\n",
    "# 模型测试\n",
    "import sys\n",
    "sys.path.append('/home/aistudio/external-libraries')\n",
    "\n",
    "import paddle\n",
    "from ppdiffusers import StableDiffusionXLPipeline\n",
    "import time, os\n",
    "from PIL import PngImagePlugin  \n",
    "\n",
    "\n",
    "HOME_DIR = os.path.expanduser('~') \n",
    "\n",
    "def custom_save_imgae(image, metadata, root, model_dir, *args):\n",
    "    outpath = f\"{root}/{model_dir.split('/')[-1]}\"\n",
    "    os.makedirs(outpath, exist_ok=True)\n",
    "\n",
    "    extra = '_'.join(args) if args else ''\n",
    "    # 创建PngInfo对象  \n",
    "    png_info = PngImagePlugin.PngInfo()  \n",
    "    # 添加文本元数据  \n",
    "    for key, value in metadata.items():  \n",
    "        if not isinstance(value, str):\n",
    "            value = str(value)\n",
    "        png_info.add_text(key, value)\n",
    "    image.save(os.path.join(outpath, f\"{extra}{time.strftime('%Y%m%d_%H%M%S', time.localtime())}.png\"), 'PNG', pnginfo=png_info)\n",
    "\n",
    "model_dir = [\n",
    "    \"Animagine-Xl-3.1\", \n",
    "    \"Pony_Pencil-Xl-V1.0.2\", \n",
    "    \"Ponydiffusionv6Xl_V6Turbodpomerge\",\n",
    "    \"Realvisxl_V4.0_Lightning\",\n",
    "    \"Realvisxl_V4.0\",\n",
    "][-1]\n",
    "\n",
    "pipe = StableDiffusionXLPipeline.from_pretrained(\n",
    "    model_dir, \n",
    "    paddle_dtype=paddle.float16\n",
    ")\n",
    "pipe.enable_xformers_memory_efficient_attention()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "from ppdiffusers import EulerDiscreteScheduler, DDPMScheduler, EulerAncestralDiscreteScheduler, KDPM2AncestralDiscreteScheduler\n",
    "pipe.scheduler = DDPMScheduler.from_config(pipe.scheduler.config)\n",
    "# pipe.scheduler = EulerDiscreteScheduler.from_config(pipe.scheduler.config)\n",
    "# pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)\n",
    "# pipe.scheduler = KDPM2AncestralDiscreteScheduler.from_config(pipe.scheduler.config)\n",
    "print(\n",
    "\"\"\"\n",
    "推荐尺寸：\n",
    "768 x 1344: Vertical (9:16)\n",
    "912 x 1144: Portrait (4:5)\n",
    "1024 x 1024: Square (1:1)\n",
    "1184 x 888: Photo (4:3)\n",
    "1256 x 840: Landscape (3:2)\n",
    "1368 x 768: Widescreen (16:9)\n",
    "1568 x 672: Cinematic (21:9)\n",
    "\"\"\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# 穿搭\n",
    "outfit_examples = [  \n",
    "    {  \n",
    "        \"color\": \"Pink\",  \n",
    "        \"description\": \"A sweet pink floral print dress paired with white sneakers and a pastel pink cardigan sweater. Accessorize with a pink headband and delicate jewelry.\",  \n",
    "        \"english_description\": \"A sweet pink floral print dress paired with white sneakers and a pastel pink cardigan sweater. Accessorize with a pink headband and delicate jewelry.\"  \n",
    "    },  \n",
    "    {  \n",
    "        \"color\": \"White\",  \n",
    "        \"description\": \"A crisp white cotton dress with lace details and a denim jacket. Add a pair of white sneakers and simple gold jewelry for a casual yet elegant look.\",  \n",
    "        \"english_description\": \"A crisp white cotton dress with lace details and a denim jacket. Add a pair of white sneakers and simple gold jewelry for a casual yet elegant look.\"  \n",
    "    },  \n",
    "    {  \n",
    "        \"color\": \"Light Blue\",  \n",
    "        \"description\": \"A light blue denim skirt paired with a white crop top and sneakers. Complete the look with a denim jacket and a blue scarf.\",  \n",
    "        \"english_description\": \"A light blue denim skirt paired with a white crop top and sneakers. Complete the look with a denim jacket and a blue scarf.\"  \n",
    "    },  \n",
    "    {  \n",
    "        \"color\": \"Yellow\",  \n",
    "        \"description\": \"A sunny yellow sundress with a floral pattern and sandals. Accessorize with a yellow belt and a straw hat for a summery vibe.\",  \n",
    "        \"english_description\": \"A sunny yellow sundress with a floral pattern and sandals. Accessorize with a yellow belt and a straw hat for a summery vibe.\"  \n",
    "    },  \n",
    "    {  \n",
    "        \"color\": \"Purple\",  \n",
    "        \"description\": \"A deep purple chiffon dress with lace sleeves and a black belt. Pair with black heels and delicate silver jewelry for a romantic evening outfit.\",  \n",
    "        \"english_description\": \"A deep purple chiffon dress with lace sleeves and a black belt. Pair with black heels and delicate silver jewelry for a romantic evening outfit.\"  \n",
    "    },  \n",
    "    {  \n",
    "        \"color\": \"Pastel Colors (Candy Colors)\",  \n",
    "        \"description\": \"A pastel green skirt paired with a pastel pink blouse and white sneakers. Accessorize with a matching pastel color handbag and earrings.\",  \n",
    "        \"english_description\": \"A pastel green skirt paired with a pastel pink blouse and white sneakers. Accessorize with a matching pastel color handbag and earrings.\"  \n",
    "    },  \n",
    "    {  \n",
    "        \"color\": \"Macaron Colors\",  \n",
    "        \"description\": \"A sky blue macaron dress with white lace trim and sandals. Complete the ensemble with a pastel blue hat and a delicate necklace.\",  \n",
    "        \"english_description\": \"A sky blue macaron dress with white lace trim and sandals. Complete the ensemble with a pastel blue hat and a delicate necklace.\"  \n",
    "    }  \n",
    "]  \n",
    "  \n",
    "# 输出列表  \n",
    "for example in outfit_examples:  \n",
    "    print(example[\"english_description\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 游戏名\n",
    "games = [\n",
    "    \"GenShion Impact\",\n",
    "    \"neon genesis evangelion\",\n",
    "][0]\n",
    "# 角色名\n",
    "rolers = [\n",
    "    \"Sangonomiya Kokomi\",\n",
    "    \"KeQing\",\n",
    "    \"souryuu asuka langley\"\n",
    "][1]\n",
    "roler_scale = 1.0\n",
    "# 服装\n",
    "clothes = [\n",
    "    \"Deep-V SunDress\",\n",
    "    \"QiPao\",\n",
    "    \"Dopamine Girl Floral Print Dress Set\", \n",
    "    \"Deep-V Dopamine-Inspired Floral Print Dress Set for Girls\",\n",
    "    \"Cheerful Dopamine Girl's Exuberant Floral Print A-Line Dress\",\n",
    "    \"\"\n",
    "][-1]\n",
    "cloth_scale = 1.0\n",
    "# 颜色\n",
    "color = [\n",
    "    \"yellow\",\n",
    "    \"greenish\",\n",
    "    \"pink-green\",\n",
    "    \"light blue\",\n",
    "][0]\n",
    "color_scale = 1.1\n",
    "# 脖子装饰\n",
    "necklace = [\n",
    "    \"\",\n",
    "    \"necklace, turtleneck\",\n",
    "][0]\n",
    "outfit = \"\" ##outfit_examples[6]['english_description']\n",
    "prompt = f\"full-length front photograph, {games} roler {rolers}:{roler_scale}, {outfit}, solo, slim, perfect face, look at viewer,off-shoulders, {color}:{color_scale}, {clothes}:{cloth_scale}, standing, bangs, single hair bun, long hair, grey eyes, parted lips, \" \\\n",
    "    f\"jewelry, {necklace}, masterpiece, best quality, highly detailed\"\n",
    "\n",
    "negative_prompt = \"nsfw, lowres, (bad), multy girls, text, bad fingers, extra fingers, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]\"\n",
    "\n",
    "image = pipe(\n",
    "    prompt, \n",
    "    negative_prompt=negative_prompt,\n",
    "    width=768,\n",
    "    height=1344, \n",
    "    guidance_scale=3,\n",
    "    num_inference_steps=30, \n",
    "    target_size=(1024,1024),\n",
    "    original_size=(4096,4096),\n",
    "    # generator=paddle.Generator().manual_seed(42)\n",
    ").images[0]\n",
    "paddle.device.cuda.empty_cache()\n",
    "\n",
    "metadata = {  \n",
    "    'Title': 'My Image Title',  \n",
    "    'Author': 'John Doe'  \n",
    "} \n",
    "root = HOME_DIR + '/out_puts'\n",
    "custom_save_imgae(\n",
    "    image, \n",
    "    metadata, \n",
    "    root, \n",
    "    model_dir, \n",
    "    games, \n",
    "    rolers,\n",
    ")\n",
    "image"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# PPdiffusers WebUI\n",
    "\n",
    "![](https://ai-studio-static-online.cdn.bcebos.com/406909bcb58b4097b7abac28b1807153918314ca46ec41fdb86e15da02263a98)\n",
    "\n",
    "\n",
    "克隆仓库\n",
    "```bash\n",
    "git clone https://gitee.com/Covirtue/PPdiffusersWebUI.git\n",
    "```\n",
    "\n",
    "测试api\n",
    "\n",
    "进入`PPdiffusersWebUI`目录后，运行 `main.ipynb`。\n",
    "\n",
    "绝对路径的是本地模型，需要输入到优先输入框。\n",
    "\n",
    "![](https://ai-studio-static-online.cdn.bcebos.com/cd609edb22014a879eda0a60bb20eb40d16ef3114f4f4dba86da5a5032c10e07)\n",
    "\n",
    "\n",
    "启动webui\n",
    "\n",
    "进入`PPdiffusersWebUI`目录后，\n",
    "*双击运行* `webui_adapter.gradio.py`。\n",
    "\n",
    "或者\n",
    "*双击运行* `webui_ctr.gradio.py`。\n",
    "\n",
    "或者\n",
    "*双击运行* `webui.gradio.py`, 16GB GPU可运行。(将权重加载到cpu使用时再加载回gpu，会牺牲速度但是可以换得超分模型的执行，可以通过`Load To CPU`选项关闭。)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "!git clone https://gitee.com/Covirtue/PPDiffusersWebUI.git"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "!pip install -r requirements.txt --user"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "重启内核，进入`PPDiffusersWebUI`双击运行`webui.gradio.py`即可，16GB GPU 可运行。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "py35-paddle1.2.0"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.10"
  },
  "toc-autonumbering": true
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
